<?php
namespace App\Logic\Amazon\AdsApi;

use GuzzleHttp\Client as GHClient;
use GuzzleHttp\Exception\GuzzleException;

class RequiredConfig
{
    private static $_instance = null;

    public static function getInit(): ?RequiredConfig
    {
        if(!is_object(self::$_instance)){
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    private const EXPIRES_IN_BEFORE = 600;//提前10分钟失效，重新获取ACCESS_TOKEN
    private const ACCESS_TOKEN_CACHE_KEY = 'Oauth-Access-token-';
    private const CLIENT_ID = 'amzn1.application-oa2-client.8b7c25028e0c4f21a9fa8b4c1667021e';
    private const CLIENT_SECRET = '07380e33d92798756edfc876fa9614057971685618bcc2fd241f1b3184a15be7';
    private const CLIENT_SECRET_FOR_DO_REFRESH_TOKEN = 'amzn1.oa2-cs.v1.07380e33d92798756edfc876fa9614057971685618bcc2fd241f1b3184a15be7';

    public function configuration($accountId, $refreshToken, $region, $configurationOptions = []): ?array
    {
        try {
            $accessToken = $this->_doRefreshToken($accountId, $refreshToken);
        } catch (GuzzleException $e) {
            report('[账号ID:'.$accountId.",_doRefreshToken() fail ]" . $e->getTraceAsString());
            return null;
        }
        if(!$accessToken){
            return null;
        }
        return array_merge(
            [
                'accountId' => $accountId,//日志记录
                'clientId' => self::CLIENT_ID, //客户端id
                'clientSecret' => self::CLIENT_SECRET, //客户端秘钥
                'region' => $region, //地区
                'accessToken' => $accessToken, //token
                'refreshToken' => $refreshToken, //刷新令牌
                'sandbox' => false,
                'saveFile' => false,
                'apiVersion' => '',//需要指定时可以配置，不需要时可以去掉
                'sbVersion' => '',//需要指定时可以配置，不需要时可以去掉
                'sdVersion' => '',//需要指定时可以配置，不需要时可以去掉
                'spVersion' => '',//需要指定时可以配置，不需要时可以去掉
                'portfoliosVersion' => '',//需要指定时可以配置，不需要时可以去掉
                'reportsVersion' => '',//需要指定时可以配置，不需要时可以去掉
                'appUserAgent' => 'Amazon advertising API library',//需不需要都不可以去掉
                'deleteGzipFile' => false,//未知参数
                'guzzleProxy' => '',
                'isUseProxy' => false,//为true时，需同时配置curlProxyType为'socks5'，curlProxy
//            'curlProxy' => '',//isUseProxy为false时，可以去掉
//            'curlProxyType' => '',//isUseProxy为false时，可以去掉
//            'headerAccept' => 'application/vnd.getasyncreportresponse.v3+json',//'application/json'，可以去掉
            ],
            $configurationOptions
        );
    }

    /**
     * @param $accountId
     * @param $refreshToken
     * @return \Illuminate\Cache\CacheManager|\Illuminate\Contracts\Foundation\Application|mixed|null
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    private function _doRefreshToken($accountId,$refreshToken): mixed
    {
        $cacheKey = self::ACCESS_TOKEN_CACHE_KEY.$accountId;
        $accessToken = cache($cacheKey);
        if($accessToken){
            return $accessToken;
        }
        $client = new GHClient();
        $response = $client->post('https://api.amazon.com/auth/o2/token', [
            'form_params' => [
                'grant_type' => 'refresh_token',
                'refresh_token' => $refreshToken,
                'client_id' => self::CLIENT_ID,
                'client_secret' => self::CLIENT_SECRET_FOR_DO_REFRESH_TOKEN,
            ],
            'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8'
        ]);
        $body = $response->getBody();
        if($response->getStatusCode() == 200){
            $data = json_decode($body, true);
            if (is_array($data) && array_key_exists("access_token", $data)) {
                cache([$cacheKey => $data['access_token']], $data['expires_in'] - self::EXPIRES_IN_BEFORE);
                return $data['access_token'];
            }else {
                report('[账号ID:'.$accountId.",Unable to refresh token. 'access_token' not found in body. ]" . print_r($body, true));
                return null;
            }
        }else{
            report('[账号ID:'.$accountId.",Unable to refresh token. 'access_token' not found in response. ]" . print_r($response, true));
            return null;
        }
    }
}
